package com.csjbot.weedle_auto.SerialServer


import com.csjbot.weedle_auto.SerialServer.util.bean.*
import com.csjbot.weedle_auto.serialport_util.SerialPortListener
import com.csjbot.weedle_auto.serialport_util.SerialPortUtil
import com.csjbot.weedle_auto.util.CheckConstants
import com.csjbot.weedle_auto.util.Csjlogger
import org.greenrobot.eventbus.EventBus

/**
 * Created by Administrator on 2016/6/24 0024.
 */
class SerialPortServer : SquireAction() {
    /**
     * close serial port
     * 关闭串口
     */
    fun closeSerialPort() {
        serialPortUtil.closeSerialPort()
    }

    val isOpen: Boolean
        get() = true

    /**
     * open serial port
     * 打开串口
     */
    fun openSerialPort(bt: Int, path: String) {
//        Csjlogger.info("chenqi action thread !")
        serialPortUtil = SerialPortUtil(bt, path, object : SerialPortListener {
            override fun onDataReceived(buffer: ByteArray, size: Int) {
                if (buffer[0] == SerialPortConstants.OTHER_HEADER) {
//                    Csjlogger.info("chenqi serialPortListener in {}" + NetDataTypeTransform.getBinaryStrFromByteArr(buffer))
                    val serialPortOtherBean = SerialPortOtherBean(
                            buffer[1].toInt()
                            , buffer[2].toInt()
                            , buffer[3].toInt()
                            , buffer[4].toInt())
                    EventBus.getDefault().post(SerialPortEvents(SerialPortEvents.Event.OTHER, serialPortOtherBean))
                } else {
                    //                Csjlogger.info("chenqi serialPortListener in3 {}", NetDataTypeTransform.dumpHex(buffer));
                    val packet = SerialPacket(buffer)
                    if (packet.dataLen < 0) {
                        return
                    }
                    parseCmd(packet)
                }
            }
        })
    }


    /**
     * reset 重置语音板
     *
     *
     */
    public override fun reset() {
        val packet = SerialPacket(CheckConstants.Type_UP.SCR_PC, CheckConstants.Type_UP.REF_CMD, CheckConstants.Type_UP.RESET, CheckConstants.Type_UP.RESET_DATALEN)
        serialPortUtil.sendData(packet.bytes)
    }


    public override fun face(kinds: ByteArray) {
        val packet = SerialPacket(CheckConstants.Type_UP.SCR_PC, CheckConstants.Type_UP.REF_CMD, CheckConstants.Type_UP.FACE, kinds, CheckConstants.Type_UP.FACE_DATALEN)
        serialPortUtil.sendData(packet.bytes)
    }

    public override fun putOtherOrder() {
        val packet = SerialPacket(SerialPortConstants.OTHER.SRC, SerialPortConstants.OTHER.REF, SerialPortConstants.OTHER.CMD, SerialPortConstants.OTHER.LENGTH)
        serialPortUtil.sendData(packet.bytes)
        Csjlogger.info("UartConnectRK3288 send  {}", packet.bytes)
    }

    public override fun putSnUp() {
        val packet = SerialPacket(SerialPortConstants.SN_UP.SRC, SerialPortConstants.SN_UP.REF, SerialPortConstants.SN_UP.CMD, SerialPortConstants.SN_UP.LENGTH)
        serialPortUtil.sendData(packet.bytes)
//        Csjlogger.info("UartConnectRK3288 send  {}", packet.bytes)
    }

    public override fun putSnDown() {
        val packet = SerialPacket(SerialPortConstants.SN_DOWN.SRC, SerialPortConstants.SN_DOWN.REF, SerialPortConstants.SN_DOWN.CMD, SerialPortConstants.SN_DOWN.LENGTH)
        serialPortUtil.sendData(packet.bytes)
//        Csjlogger.info("UartConnectRK3288 send  {}", packet.bytes)
    }

    init {
        // v--- `clientService` is not injected by spring yet.
    }


//    private var s: SerialPortServer? = null
//        get() {
//            if (field == null)
//                return SerialPortServer()
//            return field
//        }

    private object Chenqi {
        val instance = SerialPortServer()
    }

    companion object {
        /**
         * 为了保证在类的加载过程中不会出现重复加载，可以使用jvm的线程安全机制来实现单例
         *
         */
        fun createSerialPortServer() = Chenqi.instance

        var serialPortUtil: SerialPortUtil = SerialPortUtil()

        //        /**
//         * lazy在确保为一个实例的情况下，进行有序的加载，
//         */
//        val serial by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) {
//            SerialPortServer()
//        }
//
//        /**
//         * 关键字Volatile有序加载，java在1.5版本中添加进去的
//         */
//        private @Volatile
//        var ins: SerialPortServer? = null
//
//        /**
//         * 唯一单例
//         */
//        @Synchronized
//        fun get(): SerialPortServer {
//            if (ins == null) {
//                synchronized(SerialPortServer) {
//                    if (ins == null) {
//                        ins = SerialPortServer()
//                    }
//                }
//            }
//            return ins!!
//        }


        /**
         * 判断某种类型
         *
         * @param p
         * @param
         */
        fun parseCmd(p: SerialPacket) {
            when (p.cmd) {
                CheckConstants.Type_DOWN.WAKEUP ->
                    EventBus.getDefault().post(SerialPortEvents(SerialPortEvents.Event.WAKEUP))
                CheckConstants.Type_DOWN.GRAVITY -> {
                    val tuch = p.data[0].toInt()
                    EventBus.getDefault().post(SerialPortEvents(SerialPortEvents.Event.TOUCH, tuch))
                }
                CheckConstants.Type_DOWN.OA ->
                    //避障
                    try {
                        val weight = p.data[0].toInt()
                        EventBus.getDefault().post(SerialPortEvents(SerialPortEvents.Event.OA, weight))
                        //                    squireListener.oa(weight);
                        //                    Csjlogger.info("UartConnectRK3288 SquirePacketParser{}", "weight" + weight);
                    } catch (e: ArrayIndexOutOfBoundsException) {
                        Csjlogger.error("Serial 异常{} ", "指针越界 OA")
                    }

                CheckConstants.Type_DOWN.INFRARED ->
                    //0,2,4,8,16 前左，前中，前右，后左，后右。
                    try {
                        val infrared = p.data[0].toInt()
                        EventBus.getDefault().post(SerialPortEvents(SerialPortEvents.Event.INFRARED, infrared))
                        //                    squireListener.infrared(infrared);
                        //                    Csjlogger.info("UartConnectRK3288 SquirePacketParser{}", "infrared" + infrared);
                    } catch (e: ArrayIndexOutOfBoundsException) {
                        Csjlogger.error("Serial 异常{} ", "指针越界 INFRARED")
                    }

                CheckConstants.Type_DOWN.SN_PART -> {
//                    Csjlogger.error("Serial SN_PART{} ", CheckConstants.Type_DOWN.SN_PART.toString() + "")
                    try {
//                        Csjlogger.info("UartConnectRK3288 SquirePacketParser{}", p.bytes)
                    } catch (e: Exception) {
                        e.printStackTrace()
                    }
                    EventBus.getDefault().post(SerialPortEvents(SerialPortEvents.Event.SNUP, NetDataTypeTransform.getSn(p.data)))
                }
                CheckConstants.Type_DOWN.SN_BOTTOM -> {
//                    Csjlogger.error("Serial SN_BOTTOM{} ", CheckConstants.Type_DOWN.SN_BOTTOM.toString() + "")
                    try {
//                        Csjlogger.info("UartConnectRK3288 SquirePacketParser{}" + NetDataTypeTransform.dumpHex(p.bytes))
                    } catch (e: Exception) {
                        e.printStackTrace()
                    }
                    EventBus.getDefault().post(SerialPortEvents(SerialPortEvents.Event.SNDOWN, NetDataTypeTransform.getSn(p.data)))
                }
                else -> {
                }
            }
        }
    }
}
